﻿using Web.ViewModels;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Infrastructure.Identity;
using System;
using ApplicationCore.Interfaces;
using Web;
using Microsoft.AspNetCore.Authentication;
using ApplicationCore.Entities;

namespace Web.Controllers
{



	[Route("[controller]/[action]")]
	public class AccountController : Controller
	{
		private readonly UserManager<ApplicationUser> _userManager;
		private readonly SignInManager<ApplicationUser> _signInManager;
		private readonly IAsyncRepository<ApplicationUserLoginLog> _loginLogRepo;
		private readonly IAsyncRepository<Room> _roomRepo;

		public AccountController(
			UserManager<ApplicationUser> userManager,
			SignInManager<ApplicationUser> signInManager, 
			IAsyncRepository<ApplicationUserLoginLog> loginLogRepo,
			IAsyncRepository<Room> roomRepo
			)
		{
			_userManager = userManager;
			_signInManager = signInManager;
			_loginLogRepo = loginLogRepo;
			_roomRepo = roomRepo;

		}

		// GET: /Account/SignIn 
		[HttpGet]
		[AllowAnonymous]
		public async Task<IActionResult> SignIn(string returnUrl = null)
		{
			await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

			ViewData["ReturnUrl"] = returnUrl;
			if (!String.IsNullOrEmpty(returnUrl) &&
				returnUrl.ToLower().Contains("checkout"))
			{
				ViewData["ReturnUrl"] = "/Home/Index";
			}

			return View();
		}

		// POST: /Account/SignIn
		[HttpPost]
		[AllowAnonymous]
		[ValidateAntiForgeryToken]
		[AddLoginLogWithFactory(LoginOptType = OptType.SignIn)]
		//[TypeFilter(typeof(AddLoginLogWithFactoryAttribute),Arguments =new object[] { OptType.SignIn,LogSource.Attribute})]
		public async Task<IActionResult> SignIn(LoginViewModel model, string returnUrl = null)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }
            ViewData["ReturnUrl"] = returnUrl;

            var result = await _signInManager.PasswordSignInAsync(model.Name, model.Password, model.RememberMe, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                string anonymousBasketId = Request.Cookies[Constants.ZB_COOKIENAME];
                if (!String.IsNullOrEmpty(anonymousBasketId))
                {
                    //await _basketService.TransferBasketAsync(anonymousBasketId, model.Email);
                    Response.Cookies.Delete(Constants.ZB_COOKIENAME);
                }
				

				return RedirectToLocal(returnUrl);
            }
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
		[AddLoginLogWithFactory(LoginOptType = OptType.SignOut)]
		public async Task<ActionResult> SignOut()
        {
            await _signInManager.SignOutAsync();

            return RedirectToAction(nameof(HomeController.Index), "Index");
        }

        [AllowAnonymous]
        public IActionResult Register()
        {
            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
                var result = await _userManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    await _signInManager.SignInAsync(user, isPersistent: false);
                    return RedirectToLocal(returnUrl);
                }
                AddErrors(result);
            }
            // If we got this far, something failed, redisplay form
            return View(model);
        }

        private IActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction(nameof(HomeController.Index), "Home");
            }
        }

        private void AddErrors(IdentityResult result)
        {
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError("", error.Description);
            }
        }
    }
}
